﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;


namespace THZFrm {
    public partial class Form1 : Form {
        private delegate void SetCloseback();
        private delegate void StatusChange(IntPtr status);    //获取关闭状态
        private delegate void GetStarParaData(IntPtr starpara, bool bstar);

        private StatusChange statusChange = null;
        private GetStarParaData getStarParaData = null;

        private uint uStatus = 0;
        private byte[] recvStarData = new byte[1016];
        private int[] uIPoints = new int[254];
        private int[] uQPoints = new int[254];
        private ulong[] Parashow = new ulong[6];
        //private double[] dbBER_TXT = new double[100];
        //private int dbBERNum = 0;

        //private bool bEnd = false;
        private VideoPlayer videoPlayer;
        //bool bCameraOpen = false;         //摄像头是否已经打开
        //bool bVideoCapture = false;         //是否在显示视频
        int nConnected = 0;                 //是否与服务器连接，同时也是连接失败计数器

        public Form1() {
            InitializeComponent();

            statusChange = new StatusChange(UpdateStatus);
            getStarParaData = new GetStarParaData(UpdateStarParaStatus);

            videoPlayer = new VideoPlayer();

            Init(videoPlayer.getData, videoPlayer.getData, statusChange, getStarParaData);
            SetIsHost(false);
        }

        // 根据DLL的回调值更新UI的状态
        private void UpdateStatus(IntPtr status) {
            this.Invoke((Action)delegate {
                int[] s = new int[5];
                Marshal.Copy(status, s, 0, 5);
                if(s[0] == 0) {
                    // 服务器连接中断
                    //stslabel.Text = "未连接服务器";
                    ConnectSrvBtn.Text = "连接服务器";
                    // TODO 重连逻辑需要重写，目前会导致程序无法正常关闭
                    //if(nConnected > 0) {
                    //    // 非主动中断
                    //    if(nConnected > 5) {
                    //        // 最多重试5次
                    //        nConnected = 0;
                    //    } else {
                    //        // 等待1秒后自动重连上一次的IP和端口
                    //        Delay(1000);
                    //        ConnectTCPSrv(0, null);
                    //        nConnected++;
                    //    }
                    //}
                    nConnected = 0;
                } else {
                    nConnected = 1;
                    //stslabel.Text = "已连接服务器";
                    ConnectSrvBtn.Text = "断开连接";
                }
            });


        }

        private void CloseForm() {
            try {
                if(this.InvokeRequired) {
                    SetCloseback d = new SetCloseback(CloseForm);
                    this.Invoke(d);
                } else {
                    Close();
                }
            } catch(Exception ex) {
            }
        }

        private void Form1_Closing(object sender, FormClosingEventArgs e) {
            if(nConnected > 0) {
                ConnectSrvBtn_Click(null, null);
            }
            CleanMemory();
            //SDL.SDL_Quit();
            videoPlayer.Close();
        }

        //开始播放视频
        //private void startBtn_Click(object sender, EventArgs e) {
        //    startBtn.Enabled = false;
        //    this.Invoke((Action)delegate {
        //        if(bVideoCapture) {
        //            PauseCapture();
        //            bVideoCapture = false;
        //            //startBtn.Text = "开始";
        //        } else {

        //            IntPtr ptr = GetVideoDeviceInfo();
        //            string lstVideoName = Marshal.PtrToStringAnsi(ptr);
        //            string[] strName = lstVideoName.Split(';');
        //            if(strName.Length == 1) {
        //                lstVideoName = strName[0];
        //            } else {
        //                lstVideoName = strName[1];
        //            }
        //            if(OpenVideoDevice(lstVideoName) != 0) {
        //                MessageBox.Show("打开摄像头失败!");
        //                startBtn.Enabled = true;
        //                return;
        //            }

        //            StartCapture();
        //            bVideoCapture = true;
        //            //startBtn.Text = "暂停";
        //            stopBtn.Enabled = true;
        //        }
        //    });
        //}

        ////停止播放视频
        //private void stopBtn_Click(object sender, EventArgs e) {
        //    stopBtn.Enabled = false;
        //    if(bVideoCapture) {
        //        StopCapture();
        //        bVideoCapture = false;
        //        startBtn.Enabled = true;
        //        //startBtn.Text = "开始";
        //    }
        //}

        //连接TCP服务器
        private void ConnectSrvBtn_Click(object sender, EventArgs e) {
            this.Invoke((EventHandler)(delegate {
                ConnectSrvBtn.Enabled = false;
                if(nConnected == 0) {
                    if(-1 == ConnectTCPSrv(Convert.ToInt32(SrvPortTextbox.Text.ToString()), SrvIPTextBox.Text.ToString())) {
                        MessageBox.Show("连接服务器失败！");
                    } else {
                        //nConnected = 1;
                        StartCapture();
                        //bVideoCapture = true;
                    }
                } else {
                    StopCapture();
                    DisConnetTCPSrv();
                    videoPlayer.Reset();
                }
                ConnectSrvBtn.Enabled = true;
            }));
        }

        private void UpdateStarParaStatus(IntPtr starpara, bool bstar) {
            Marshal.Copy(starpara, recvStarData, 0, 1016);
            if(recvStarData[7] == 0) {
                return;
            }

            if(bstar)  //星座图数据
            {
                int nIQsel = 0;
                for(int i = 0; i < 1016; i += 4) {
                    uStatus = (uint)(recvStarData[i + 1] * Math.Pow(2.0, 16) + recvStarData[i + 2] * Math.Pow(2.0, 8) + recvStarData[i + 3]);
                    uIPoints[nIQsel] = (int)((uStatus >> 12) & 0xFFF);
                    if((uIPoints[nIQsel] & 0x800) != 0) {
                        uIPoints[nIQsel] -= 4096;
                    }
                    uQPoints[nIQsel] = (int)(uStatus & 0xFFF);
                    if((uQPoints[nIQsel] & 0x800) != 0) {
                        uQPoints[nIQsel] -= 4096;
                    }
                    nIQsel++;
                }

                this.Invoke((EventHandler)(delegate {
                    chart1.Series[0].Points.Clear();

                    for(int i = 0; i < 254; i++) {
                        chart1.Series[0].Points.AddXY(uIPoints[i], uQPoints[i]);
                    }
                }));

            } else   //传参显示
              {
                int nsel = 0;
                for(int i = 0; i < 6; i++) {
                    // 应该先对数据进行强制类型转换了再进行后续运算
                    Parashow[i] = ((ulong)(recvStarData[nsel++]) << 56) + ((ulong)(recvStarData[nsel++]) << 48) +
                                                ((ulong)(recvStarData[nsel++]) << 40) + ((ulong)(recvStarData[nsel++]) << 32) +
                                                ((ulong)(recvStarData[nsel++]) << 24) + ((ulong)(recvStarData[nsel++]) << 16) +
                                                ((ulong)(recvStarData[nsel++]) << 8) + (recvStarData[nsel++]);

                }
                double dbBER = 0;
                if(Parashow[5] != 0)
                    dbBER = (double)(Parashow[4] / (double)Parashow[5]);
                string finalstr = "0";
                if(dbBER != 0) {
                    if(dbBER < 10e-6) {
                        string str = dbBER.ToString();
                        int len = str.Length;

                        int pos = Convert.ToInt32(str.IndexOf('E'));
                        finalstr = str.Substring(0, 6) + str.Substring(pos, len - pos);

                    } else {
                        finalstr = dbBER.ToString();
                    }
                }
                this.Invoke((EventHandler)(delegate {
                    textBox_FrameNum.Text = (Parashow[0] * 5).ToString();
                    textBox_FrameDropNum.Text = (Parashow[1] * 5).ToString();
                    textBox_CRC_Good.Text = (Parashow[2] * 5).ToString();
                    textBox_CRC_Bad.Text = (Parashow[3] * 5).ToString();
                    textBox_Errbit.Text = (Parashow[4] * 5).ToString();
                    textBox_TotalErrbit.Text = (Parashow[5] * 5).ToString();
                    textBox_BER.Text = finalstr;
                }));
            }
        }

        #region DLL传递函数以及参数
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private static extern void Init(
                VideoPlayer.GetData getDataSDI1, VideoPlayer.GetData getDataSDI2, StatusChange sChange, GetStarParaData StarParaData);
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private static extern IntPtr GetVideoDeviceInfo();
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private static extern int OpenVideoDevice(string strVideoName);
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private static extern int CloseVideoDevice();
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private extern static int StartCapture();
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private extern static int PauseCapture();
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private extern static int StopCapture();
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private extern static void CleanMemory();
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private static extern int ConnectTCPSrv(int nSrvPort, string strSrvIPAddr);
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private static extern void DisConnetTCPSrv();
        [DllImport("VideoDecodeDll", CharSet = CharSet.Ansi)]
        private static extern void SetIsHost(bool b);

        #endregion

    }
}
